package com.zenika.zentracker.hibernate.info;

import java.io.Serializable;

/**
 * Class identifying a collection. It is the Key of a Collection.
 * 
 * Before a transaction completion, and during the different flush events that can happen, a collection can be modified.<br/>
 * 
 * This class is used to identify a collection so different events (during different flushes) can be related to the
 * appropriate collection.<br/>
 * 
 * @author Zenika
 */
public class CollectionKey {

    /**
     * The Key used for a collection by the ORM framework.
     */
    private Serializable key;

    /**
     * The role of a Collection.<br/> Example : For a Country object, with an attribute named "cities" the role will be :
     * "Country.cities"
     */
    private String role;

    /**
     * The instance owner of the collection the has been modified. Example : A Country instance if the "cities" property
     * of type Collection has been modified.
     */
    private Object owner;

    /**
     * Constructor used for building a unique key.
     * 
     * @param key The Key used by the ORM framework
     * @param role The name of the collection
     * @param owner The instance owning the modified collection
     */
    public CollectionKey(final Serializable key, final String role, final Object owner) {
        this.key = key;
        this.role = role;
        this.owner = owner;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer();

        buffer.append("Collection [").append(key).append(" - ").append(role).append("] for Entity ").append(owner);

        return buffer.toString();
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((key == null) ? 0 : key.hashCode());
        result = prime * result + ((owner == null) ? 0 : owner.hashCode());
        result = prime * result + ((role == null) ? 0 : role.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (obj == null)
            return false;

        if (getClass() != obj.getClass())
            return false;

        final CollectionKey other = (CollectionKey) obj;
        if (key == null) {
            if (other.key != null)
                return false;
        } else if (!key.equals(other.key))
            return false;

        if (owner == null) {
            if (other.owner != null)
                return false;
        } else if (!owner.equals(other.owner))
            return false;

        if (role == null) {
            if (other.role != null)
                return false;
        } else if (!role.equals(other.role))
            return false;

        return true;
    }

}
